Calculate chain_diff for DependencyDescriptor from GenericFrameInfo

Bug: webrtc:10342
Change-Id: Ic88d58dc011c641a3b251eef74064066975296fa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/175652
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31331}
diff --git a/call/BUILD.gn b/call/BUILD.gn
index a9037c3..a5e21b1 100644
--- a/call/BUILD.gn
+++ b/call/BUILD.gn
@@ -171,6 +171,7 @@
     "../modules/rtp_rtcp:rtp_rtcp_format",
     "../modules/rtp_rtcp:rtp_video_header",
     "../modules/utility",
+    "../modules/video_coding:chain_diff_calculator",
     "../modules/video_coding:codec_globals_headers",
     "../modules/video_coding:frame_dependencies_calculator",
     "../modules/video_coding:video_codec_interface",
diff --git a/call/rtp_payload_params.cc b/call/rtp_payload_params.cc
index 279eb58..635ed52 100644
--- a/call/rtp_payload_params.cc
+++ b/call/rtp_payload_params.cc
@@ -261,6 +261,8 @@
   generic.frame_id = frame_id;
   generic.dependencies = dependencies_calculator_.FromBuffersUsage(
       frame_type, frame_id, frame_info.encoder_buffers);
+  generic.chain_diffs =
+      chains_calculator_.From(frame_id, frame_info.part_of_chain);
   generic.spatial_index = frame_info.spatial_id;
   generic.temporal_index = frame_info.temporal_id;
   generic.decode_target_indications = frame_info.decode_target_indications;
@@ -273,6 +275,11 @@
                                   RTPVideoHeader* rtp_video_header) {
   if (codec_specific_info && codec_specific_info->generic_frame_info &&
       !codec_specific_info->generic_frame_info->encoder_buffers.empty()) {
+    if (is_keyframe) {
+      // Key frame resets all chains it is in.
+      chains_calculator_.Reset(
+          codec_specific_info->generic_frame_info->part_of_chain);
+    }
     rtp_video_header->generic =
         GenericDescriptorFromFrameInfo(*codec_specific_info->generic_frame_info,
                                        frame_id, rtp_video_header->frame_type);
diff --git a/call/rtp_payload_params.h b/call/rtp_payload_params.h
index 13b10503..fa51efd 100644
--- a/call/rtp_payload_params.h
+++ b/call/rtp_payload_params.h
@@ -19,6 +19,7 @@
 #include "call/rtp_config.h"
 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
+#include "modules/video_coding/chain_diff_calculator.h"
 #include "modules/video_coding/frame_dependencies_calculator.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 
@@ -88,6 +89,7 @@
                              RTPVideoHeader::GenericDescriptorInfo* generic);
 
   FrameDependenciesCalculator dependencies_calculator_;
+  ChainDiffCalculator chains_calculator_;
   // TODO(bugs.webrtc.org/10242): Remove once all encoder-wrappers are updated.
   // Holds the last shared frame id for a given (spatial, temporal) layer.
   std::array<std::array<int64_t, RtpGenericFrameDescriptor::kMaxTemporalLayers>,
diff --git a/call/rtp_payload_params_unittest.cc b/call/rtp_payload_params_unittest.cc
index 1045504..75860a8 100644
--- a/call/rtp_payload_params_unittest.cc
+++ b/call/rtp_payload_params_unittest.cc
@@ -32,6 +32,7 @@
 
 using ::testing::ElementsAre;
 using ::testing::IsEmpty;
+using ::testing::SizeIs;
 
 namespace webrtc {
 namespace {
@@ -388,6 +389,7 @@
       GenericFrameInfo::Builder().S(1).T(0).Dtis("S").Build();
   codec_info.generic_frame_info->encoder_buffers = {
       {/*id=*/0, /*referenced=*/false, /*updated=*/true}};
+  codec_info.generic_frame_info->part_of_chain = {true, false};
   RTPVideoHeader key_header =
       params.GetRtpVideoHeader(encoded_image, &codec_info, /*frame_id=*/1);
 
@@ -398,12 +400,14 @@
   EXPECT_THAT(key_header.generic->dependencies, IsEmpty());
   EXPECT_THAT(key_header.generic->decode_target_indications,
               ElementsAre(DecodeTargetIndication::kSwitch));
+  EXPECT_THAT(key_header.generic->chain_diffs, SizeIs(2));
 
   encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
   codec_info.generic_frame_info =
       GenericFrameInfo::Builder().S(2).T(3).Dtis("D").Build();
   codec_info.generic_frame_info->encoder_buffers = {
       {/*id=*/0, /*referenced=*/true, /*updated=*/false}};
+  codec_info.generic_frame_info->part_of_chain = {false, false};
   RTPVideoHeader delta_header =
       params.GetRtpVideoHeader(encoded_image, &codec_info, /*frame_id=*/3);
 
@@ -414,6 +418,7 @@
   EXPECT_THAT(delta_header.generic->dependencies, ElementsAre(1));
   EXPECT_THAT(delta_header.generic->decode_target_indications,
               ElementsAre(DecodeTargetIndication::kDiscardable));
+  EXPECT_THAT(delta_header.generic->chain_diffs, SizeIs(2));
 }
 
 class RtpPayloadParamsVp8ToGenericTest : public ::testing::Test {
diff --git a/common_video/generic_frame_descriptor/generic_frame_info.h b/common_video/generic_frame_descriptor/generic_frame_info.h
index 9b20707..7ac3665 100644
--- a/common_video/generic_frame_descriptor/generic_frame_info.h
+++ b/common_video/generic_frame_descriptor/generic_frame_info.h
@@ -12,6 +12,7 @@
 #define COMMON_VIDEO_GENERIC_FRAME_DESCRIPTOR_GENERIC_FRAME_INFO_H_
 
 #include <initializer_list>
+#include <vector>
 
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/string_view.h"
@@ -41,6 +42,7 @@
   ~GenericFrameInfo();
 
   absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers> encoder_buffers;
+  std::vector<bool> part_of_chain;
 };
 
 class GenericFrameInfo::Builder {