Use the generic descriptor information in the RtpFrameReferenceFinder.

Bug: webrtc:9361
Change-Id: I8d7e7ee1d3ca89283552c21c45950d4dba1c1927
Reviewed-on: https://webrtc-review.googlesource.com/100301
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24826}
diff --git a/modules/video_coding/rtp_frame_reference_finder.cc b/modules/video_coding/rtp_frame_reference_finder.cc
index 6c93c84..67414bb 100644
--- a/modules/video_coding/rtp_frame_reference_finder.cc
+++ b/modules/video_coding/rtp_frame_reference_finder.cc
@@ -84,6 +84,14 @@
 
 RtpFrameReferenceFinder::FrameDecision
 RtpFrameReferenceFinder::ManageFrameInternal(RtpFrameObject* frame) {
+  absl::optional<RTPVideoHeader> video_header = frame->GetRtpVideoHeader();
+  // TODO(bugs.webrtc.org/9772): Remove the spatial id check when the old
+  //                             generic format has been removed.
+  if (video_header && video_header->generic &&
+      video_header->generic->spatial_index != -1) {
+    return ManageFrameGeneric(frame, *video_header->generic);
+  }
+
   switch (frame->codec_type()) {
     case kVideoCodecVP8:
       return ManageFrameVp8(frame);
@@ -91,11 +99,11 @@
       return ManageFrameVp9(frame);
     default: {
       // Use 15 first bits of frame ID as picture ID if available.
-      absl::optional<RTPVideoHeader> video_header = frame->GetRtpVideoHeader();
-      absl::optional<RTPVideoHeader::GenericDescriptorInfo> generic_info =
-          video_header ? video_header->generic : absl::nullopt;
-      return ManageFrameGeneric(
-          frame, generic_info ? generic_info->frame_id & 0x7fff : kNoPictureId);
+      int picture_id = kNoPictureId;
+      if (video_header && video_header->generic)
+        picture_id = video_header->generic->frame_id & 0x7fff;
+
+      return ManageFramePidOrSeqNum(frame, picture_id);
     }
   }
 }
@@ -161,8 +169,28 @@
 }
 
 RtpFrameReferenceFinder::FrameDecision
-RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame,
-                                            int picture_id) {
+RtpFrameReferenceFinder::ManageFrameGeneric(
+    RtpFrameObject* frame,
+    const RTPVideoHeader::GenericDescriptorInfo& descriptor) {
+  if (EncodedFrame::kMaxFrameReferences < descriptor.dependencies.size()) {
+    RTC_LOG(LS_WARNING) << "Too many dependencies in generic descriptor.";
+    return kDrop;
+  }
+
+  int64_t frame_id = generic_frame_id_unwrapper_.Unwrap(descriptor.frame_id);
+  frame->id.picture_id = frame_id;
+  frame->id.spatial_layer = descriptor.spatial_index;
+
+  frame->num_references = descriptor.dependencies.size();
+  for (size_t i = 0; i < descriptor.dependencies.size(); ++i)
+    frame->references[i] = frame_id - descriptor.dependencies[i];
+
+  return kHandOff;
+}
+
+RtpFrameReferenceFinder::FrameDecision
+RtpFrameReferenceFinder::ManageFramePidOrSeqNum(RtpFrameObject* frame,
+                                                int picture_id) {
   // If |picture_id| is specified then we use that to set the frame references,
   // otherwise we use sequence number.
   if (picture_id != kNoPictureId) {
@@ -219,7 +247,7 @@
   // picture id according to some incrementing counter.
   frame->id.picture_id = frame->last_seq_num();
   frame->num_references = frame->frame_type() == kVideoFrameDelta;
-  frame->references[0] = generic_unwrapper_.Unwrap(last_picture_id_gop);
+  frame->references[0] = rtp_seq_num_unwrapper_.Unwrap(last_picture_id_gop);
   if (AheadOf<uint16_t>(frame->id.picture_id, last_picture_id_gop)) {
     seq_num_it->second.first = frame->id.picture_id;
     seq_num_it->second.second = frame->id.picture_id;
@@ -227,7 +255,7 @@
 
   last_picture_id_ = frame->id.picture_id;
   UpdateLastPictureIdWithPadding(frame->id.picture_id);
-  frame->id.picture_id = generic_unwrapper_.Unwrap(frame->id.picture_id);
+  frame->id.picture_id = rtp_seq_num_unwrapper_.Unwrap(frame->id.picture_id);
   return kHandOff;
 }
 
@@ -247,7 +275,7 @@
   if (codec_header.pictureId == kNoPictureId ||
       codec_header.temporalIdx == kNoTemporalIdx ||
       codec_header.tl0PicIdx == kNoTl0PicIdx) {
-    return ManageFrameGeneric(std::move(frame), codec_header.pictureId);
+    return ManageFramePidOrSeqNum(std::move(frame), codec_header.pictureId);
   }
 
   frame->id.picture_id = codec_header.pictureId % kPicIdLength;
@@ -396,7 +424,7 @@
 
   if (codec_header.picture_id == kNoPictureId ||
       codec_header.temporal_idx == kNoTemporalIdx) {
-    return ManageFrameGeneric(std::move(frame), codec_header.picture_id);
+    return ManageFramePidOrSeqNum(std::move(frame), codec_header.picture_id);
   }
 
   frame->id.spatial_layer = codec_header.spatial_idx;