Merged FrameBuffer3 {Next,Last}DecodableTemporalUnitRtpTimestamp() function.

Bug: webrtc:13343
Change-Id: Ic21eddd38466e6b5fd8b912b3ee2d9dc47a0ba35
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260981
Reviewed-by: Evan Shrubsole <eshr@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36756}
diff --git a/modules/video_coding/frame_buffer3.cc b/modules/video_coding/frame_buffer3.cc
index fab4ca7..3c26380 100644
--- a/modules/video_coding/frame_buffer3.cc
+++ b/modules/video_coding/frame_buffer3.cc
@@ -11,9 +11,6 @@
 #include "modules/video_coding/frame_buffer3.h"
 
 #include <algorithm>
-#include <iterator>
-#include <queue>
-#include <utility>
 
 #include "absl/algorithm/container.h"
 #include "absl/container/inlined_vector.h"
@@ -52,7 +49,7 @@
 }
 
 template <typename FrameIteratorT>
-int64_t GetTimestamp(const FrameIteratorT& it) {
+uint32_t GetTimestamp(const FrameIteratorT& it) {
   return it->second.encoded_frame->Timestamp();
 }
 
@@ -158,17 +155,9 @@
   return last_continuous_temporal_unit_frame_id_;
 }
 
-absl::optional<uint32_t> FrameBuffer::NextDecodableTemporalUnitRtpTimestamp()
-    const {
-  if (!next_decodable_temporal_unit_) {
-    return absl::nullopt;
-  }
-  return GetTimestamp(next_decodable_temporal_unit_->first_frame);
-}
-
-absl::optional<uint32_t> FrameBuffer::LastDecodableTemporalUnitRtpTimestamp()
-    const {
-  return last_decodable_temporal_unit_timestamp_;
+absl::optional<FrameBuffer::DecodabilityInfo>
+FrameBuffer::DecodableTemporalUnitsInfo() const {
+  return decodable_temporal_units_info_;
 }
 
 int FrameBuffer::GetTotalNumberOfContinuousTemporalUnits() const {
@@ -221,7 +210,7 @@
 
 void FrameBuffer::FindNextAndLastDecodableTemporalUnit() {
   next_decodable_temporal_unit_.reset();
-  last_decodable_temporal_unit_timestamp_.reset();
+  decodable_temporal_units_info_.reset();
 
   if (!last_continuous_temporal_unit_frame_id_) {
     return;
@@ -230,6 +219,7 @@
   FrameIterator first_frame_it = frames_.begin();
   FrameIterator last_frame_it = frames_.begin();
   absl::InlinedVector<int64_t, 4> frames_in_temporal_unit;
+  uint32_t last_decodable_temporal_unit_timestamp;
   for (auto frame_it = frames_.begin(); frame_it != frames_.end();) {
     if (GetFrameId(frame_it) > *last_continuous_temporal_unit_frame_id_) {
       break;
@@ -264,16 +254,23 @@
           next_decodable_temporal_unit_ = {first_frame_it, last_frame_it};
         }
 
-        last_decodable_temporal_unit_timestamp_ = GetTimestamp(first_frame_it);
+        last_decodable_temporal_unit_timestamp = GetTimestamp(first_frame_it);
       }
     }
   }
+
+  if (next_decodable_temporal_unit_) {
+    decodable_temporal_units_info_ = {
+        .next_rtp_timestamp =
+            GetTimestamp(next_decodable_temporal_unit_->first_frame),
+        .last_rtp_timestamp = last_decodable_temporal_unit_timestamp};
+  }
 }
 
 void FrameBuffer::Clear() {
   frames_.clear();
   next_decodable_temporal_unit_.reset();
-  last_decodable_temporal_unit_timestamp_.reset();
+  decodable_temporal_units_info_.reset();
   last_continuous_frame_id_.reset();
   last_continuous_temporal_unit_frame_id_.reset();
   decoded_frame_history_.Clear();
diff --git a/modules/video_coding/frame_buffer3.h b/modules/video_coding/frame_buffer3.h
index 5bcfbd2..aef26d4 100644
--- a/modules/video_coding/frame_buffer3.h
+++ b/modules/video_coding/frame_buffer3.h
@@ -31,6 +31,11 @@
 // The FrameBuffer is thread-unsafe.
 class FrameBuffer {
  public:
+  struct DecodabilityInfo {
+    uint32_t next_rtp_timestamp;
+    uint32_t last_rtp_timestamp;
+  };
+
   // The `max_size` determines the maxmimum number of frames the buffer will
   // store, and max_decode_history determines how far back (by frame ID) the
   // buffer will store if a frame was decoded or not.
@@ -56,8 +61,7 @@
 
   absl::optional<int64_t> LastContinuousFrameId() const;
   absl::optional<int64_t> LastContinuousTemporalUnitFrameId() const;
-  absl::optional<uint32_t> NextDecodableTemporalUnitRtpTimestamp() const;
-  absl::optional<uint32_t> LastDecodableTemporalUnitRtpTimestamp() const;
+  absl::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const;
 
   int GetTotalNumberOfContinuousTemporalUnits() const;
   int GetTotalNumberOfDroppedFrames() const;
@@ -87,7 +91,7 @@
   const size_t max_size_;
   FrameMap frames_;
   absl::optional<TemporalUnit> next_decodable_temporal_unit_;
-  absl::optional<uint32_t> last_decodable_temporal_unit_timestamp_;
+  absl::optional<DecodabilityInfo> decodable_temporal_units_info_;
   absl::optional<int64_t> last_continuous_frame_id_;
   absl::optional<int64_t> last_continuous_temporal_unit_frame_id_;
   video_coding::DecodedFramesHistory decoded_frame_history_;
diff --git a/modules/video_coding/frame_buffer3_unittest.cc b/modules/video_coding/frame_buffer3_unittest.cc
index 39fab88..305471f 100644
--- a/modules/video_coding/frame_buffer3_unittest.cc
+++ b/modules/video_coding/frame_buffer3_unittest.cc
@@ -111,10 +111,9 @@
   FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
                      field_trials);
 
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(),
-              Eq(absl::nullopt));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo(), Eq(absl::nullopt));
   buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build());
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
 }
 
 TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
@@ -126,14 +125,14 @@
   buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build());
   buffer.InsertFrame(
       test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build());
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
 
   EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
               ElementsAre(FrameWithId(1)));
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(20U));
   EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
               ElementsAre(FrameWithId(2)));
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(30U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(30U));
   EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
               ElementsAre(FrameWithId(3)));
 }
@@ -148,11 +147,11 @@
       test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build());
   buffer.InsertFrame(
       test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build());
-  EXPECT_THAT(buffer.LastDecodableTemporalUnitRtpTimestamp(), Eq(10U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->last_rtp_timestamp, Eq(10U));
 
   EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
               ElementsAre(FrameWithId(1)));
-  EXPECT_THAT(buffer.LastDecodableTemporalUnitRtpTimestamp(), Eq(30U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->last_rtp_timestamp, Eq(30U));
 }
 
 TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
@@ -161,10 +160,10 @@
                      field_trials);
 
   buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build());
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(20U));
 
   buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build());
-  EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U));
+  EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
 }
 
 TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {