diff --git a/modules/video_coding/jitter_buffer.cc b/modules/video_coding/jitter_buffer.cc index 933b976f68..c9314f384f 100644 --- a/modules/video_coding/jitter_buffer.cc +++ b/modules/video_coding/jitter_buffer.cc @@ -30,9 +30,6 @@ #include "system_wrappers/include/field_trial.h" namespace webrtc { -// Interval for updating SS data. -static const uint32_t kSsCleanupIntervalSec = 60; - // Use this rtt if no value has been reported. static const int64_t kDefaultRtt = 200; @@ -115,104 +112,6 @@ void FrameList::Reset(UnorderedFrameList* free_frames) { } } -Vp9SsMap::Vp9SsMap() {} -Vp9SsMap::~Vp9SsMap() {} - -bool Vp9SsMap::Insert(const VCMPacket& packet) { - const auto& vp9_header = - absl::get(packet.video_header.video_type_header); - if (!vp9_header.ss_data_available) - return false; - - ss_map_[packet.timestamp] = vp9_header.gof; - return true; -} - -void Vp9SsMap::Reset() { - ss_map_.clear(); -} - -bool Vp9SsMap::Find(uint32_t timestamp, SsMap::iterator* it_out) { - bool found = false; - for (SsMap::iterator it = ss_map_.begin(); it != ss_map_.end(); ++it) { - if (it->first == timestamp || IsNewerTimestamp(timestamp, it->first)) { - *it_out = it; - found = true; - } - } - return found; -} - -void Vp9SsMap::RemoveOld(uint32_t timestamp) { - if (!TimeForCleanup(timestamp)) - return; - - SsMap::iterator it; - if (!Find(timestamp, &it)) - return; - - ss_map_.erase(ss_map_.begin(), it); - AdvanceFront(timestamp); -} - -bool Vp9SsMap::TimeForCleanup(uint32_t timestamp) const { - if (ss_map_.empty() || !IsNewerTimestamp(timestamp, ss_map_.begin()->first)) - return false; - - uint32_t diff = timestamp - ss_map_.begin()->first; - return diff / kVideoPayloadTypeFrequency >= kSsCleanupIntervalSec; -} - -void Vp9SsMap::AdvanceFront(uint32_t timestamp) { - RTC_DCHECK(!ss_map_.empty()); - GofInfoVP9 gof = ss_map_.begin()->second; - ss_map_.erase(ss_map_.begin()); - ss_map_[timestamp] = gof; -} - -// TODO(asapersson): Update according to updates in RTP payload profile. -bool Vp9SsMap::UpdatePacket(VCMPacket* packet) { - auto& vp9_header = - absl::get(packet->video_header.video_type_header); - uint8_t gof_idx = vp9_header.gof_idx; - if (gof_idx == kNoGofIdx) - return false; // No update needed. - - SsMap::iterator it; - if (!Find(packet->timestamp, &it)) - return false; // Corresponding SS not yet received. - - if (gof_idx >= it->second.num_frames_in_gof) - return false; // Assume corresponding SS not yet received. - - vp9_header.temporal_idx = it->second.temporal_idx[gof_idx]; - vp9_header.temporal_up_switch = it->second.temporal_up_switch[gof_idx]; - - // TODO(asapersson): Set vp9.ref_picture_id[i] and add usage. - vp9_header.num_ref_pics = it->second.num_ref_pics[gof_idx]; - for (uint8_t i = 0; i < it->second.num_ref_pics[gof_idx]; ++i) { - vp9_header.pid_diff[i] = it->second.pid_diff[gof_idx][i]; - } - return true; -} - -void Vp9SsMap::UpdateFrames(FrameList* frames) { - for (const auto& frame_it : *frames) { - uint8_t gof_idx = - frame_it.second->CodecSpecific()->codecSpecific.VP9.gof_idx; - if (gof_idx == kNoGofIdx) { - continue; - } - SsMap::iterator ss_it; - if (Find(frame_it.second->Timestamp(), &ss_it)) { - if (gof_idx >= ss_it->second.num_frames_in_gof) { - continue; // Assume corresponding SS not yet received. - } - frame_it.second->SetGofInfo(ss_it->second, gof_idx); - } - } -} - VCMJitterBuffer::VCMJitterBuffer(Clock* clock, std::unique_ptr event) : clock_(clock), diff --git a/modules/video_coding/jitter_buffer.h b/modules/video_coding/jitter_buffer.h index 0d24776b67..994c1604af 100644 --- a/modules/video_coding/jitter_buffer.h +++ b/modules/video_coding/jitter_buffer.h @@ -68,40 +68,6 @@ class FrameList void Reset(UnorderedFrameList* free_frames); }; -class Vp9SsMap { - public: - typedef std::map SsMap; - Vp9SsMap(); - ~Vp9SsMap(); - - bool Insert(const VCMPacket& packet); - void Reset(); - - // Removes SS data that are older than |timestamp|. - // The |timestamp| should be an old timestamp, i.e. packets with older - // timestamps should no longer be inserted. - void RemoveOld(uint32_t timestamp); - - bool UpdatePacket(VCMPacket* packet); - void UpdateFrames(FrameList* frames); - - // Public for testing. - // Returns an iterator to the corresponding SS data for the input |timestamp|. - bool Find(uint32_t timestamp, SsMap::iterator* it); - - private: - // These two functions are called by RemoveOld. - // Checks if it is time to do a clean up (done each kSsCleanupIntervalSec). - bool TimeForCleanup(uint32_t timestamp) const; - - // Advances the oldest SS data to handle timestamp wrap in cases where SS data - // are received very seldom (e.g. only once in beginning, second when - // IsNewerTimestamp is not true). - void AdvanceFront(uint32_t timestamp); - - SsMap ss_map_; -}; - class VCMJitterBuffer { public: VCMJitterBuffer(Clock* clock, std::unique_ptr event); diff --git a/modules/video_coding/jitter_buffer_unittest.cc b/modules/video_coding/jitter_buffer_unittest.cc index f92c092835..221701bece 100644 --- a/modules/video_coding/jitter_buffer_unittest.cc +++ b/modules/video_coding/jitter_buffer_unittest.cc @@ -31,176 +31,6 @@ namespace webrtc { -namespace { -const uint32_t kProcessIntervalSec = 60; -} // namespace - -class Vp9SsMapTest : public ::testing::Test { - protected: - Vp9SsMapTest() : packet_() {} - - virtual void SetUp() { - auto& vp9_header = - packet_.video_header.video_type_header.emplace(); - packet_.video_header.is_first_packet_in_frame = true; - packet_.dataPtr = data_; - packet_.sizeBytes = 1400; - packet_.seqNum = 1234; - packet_.timestamp = 1; - packet_.markerBit = true; - packet_.frameType = VideoFrameType::kVideoFrameKey; - packet_.video_header.codec = kVideoCodecVP9; - packet_.video_header.codec = kVideoCodecVP9; - vp9_header.flexible_mode = false; - vp9_header.gof_idx = 0; - vp9_header.temporal_idx = kNoTemporalIdx; - vp9_header.temporal_up_switch = false; - vp9_header.ss_data_available = true; - vp9_header.gof.SetGofInfoVP9( - kTemporalStructureMode3); // kTemporalStructureMode3: 0-2-1-2.. - } - - Vp9SsMap map_; - uint8_t data_[1500]; - VCMPacket packet_; -}; - -TEST_F(Vp9SsMapTest, Insert) { - EXPECT_TRUE(map_.Insert(packet_)); -} - -TEST_F(Vp9SsMapTest, Insert_NoSsData) { - absl::get(packet_.video_header.video_type_header) - .ss_data_available = false; - EXPECT_FALSE(map_.Insert(packet_)); -} - -TEST_F(Vp9SsMapTest, Find) { - EXPECT_TRUE(map_.Insert(packet_)); - Vp9SsMap::SsMap::iterator it; - EXPECT_TRUE(map_.Find(packet_.timestamp, &it)); - EXPECT_EQ(packet_.timestamp, it->first); -} - -TEST_F(Vp9SsMapTest, Find_WithWrap) { - const uint32_t kSsTimestamp1 = 0xFFFFFFFF; - const uint32_t kSsTimestamp2 = 100; - packet_.timestamp = kSsTimestamp1; - EXPECT_TRUE(map_.Insert(packet_)); - packet_.timestamp = kSsTimestamp2; - EXPECT_TRUE(map_.Insert(packet_)); - Vp9SsMap::SsMap::iterator it; - EXPECT_FALSE(map_.Find(kSsTimestamp1 - 1, &it)); - EXPECT_TRUE(map_.Find(kSsTimestamp1, &it)); - EXPECT_EQ(kSsTimestamp1, it->first); - EXPECT_TRUE(map_.Find(0, &it)); - EXPECT_EQ(kSsTimestamp1, it->first); - EXPECT_TRUE(map_.Find(kSsTimestamp2 - 1, &it)); - EXPECT_EQ(kSsTimestamp1, it->first); - EXPECT_TRUE(map_.Find(kSsTimestamp2, &it)); - EXPECT_EQ(kSsTimestamp2, it->first); - EXPECT_TRUE(map_.Find(kSsTimestamp2 + 1, &it)); - EXPECT_EQ(kSsTimestamp2, it->first); -} - -TEST_F(Vp9SsMapTest, Reset) { - EXPECT_TRUE(map_.Insert(packet_)); - Vp9SsMap::SsMap::iterator it; - EXPECT_TRUE(map_.Find(packet_.timestamp, &it)); - EXPECT_EQ(packet_.timestamp, it->first); - - map_.Reset(); - EXPECT_FALSE(map_.Find(packet_.timestamp, &it)); -} - -TEST_F(Vp9SsMapTest, RemoveOld) { - Vp9SsMap::SsMap::iterator it; - const uint32_t kSsTimestamp1 = 10000; - packet_.timestamp = kSsTimestamp1; - EXPECT_TRUE(map_.Insert(packet_)); - - const uint32_t kTimestamp = kSsTimestamp1 + kProcessIntervalSec * 90000; - map_.RemoveOld(kTimestamp - 1); // Interval not passed. - EXPECT_TRUE(map_.Find(kSsTimestamp1, &it)); // Should not been removed. - - map_.RemoveOld(kTimestamp); - EXPECT_FALSE(map_.Find(kSsTimestamp1, &it)); - EXPECT_TRUE(map_.Find(kTimestamp, &it)); - EXPECT_EQ(kTimestamp, it->first); -} - -TEST_F(Vp9SsMapTest, RemoveOld_WithWrap) { - Vp9SsMap::SsMap::iterator it; - const uint32_t kSsTimestamp1 = 0xFFFFFFFF - kProcessIntervalSec * 90000; - const uint32_t kSsTimestamp2 = 10; - const uint32_t kSsTimestamp3 = 1000; - packet_.timestamp = kSsTimestamp1; - EXPECT_TRUE(map_.Insert(packet_)); - packet_.timestamp = kSsTimestamp2; - EXPECT_TRUE(map_.Insert(packet_)); - packet_.timestamp = kSsTimestamp3; - EXPECT_TRUE(map_.Insert(packet_)); - - map_.RemoveOld(kSsTimestamp3); - EXPECT_FALSE(map_.Find(kSsTimestamp1, &it)); - EXPECT_FALSE(map_.Find(kSsTimestamp2, &it)); - EXPECT_TRUE(map_.Find(kSsTimestamp3, &it)); -} - -TEST_F(Vp9SsMapTest, UpdatePacket_NoSsData) { - absl::get(packet_.video_header.video_type_header).gof_idx = - 0; - EXPECT_FALSE(map_.UpdatePacket(&packet_)); -} - -TEST_F(Vp9SsMapTest, UpdatePacket_NoGofIdx) { - EXPECT_TRUE(map_.Insert(packet_)); - absl::get(packet_.video_header.video_type_header).gof_idx = - kNoGofIdx; - EXPECT_FALSE(map_.UpdatePacket(&packet_)); -} - -TEST_F(Vp9SsMapTest, UpdatePacket_InvalidGofIdx) { - EXPECT_TRUE(map_.Insert(packet_)); - absl::get(packet_.video_header.video_type_header).gof_idx = - 4; - EXPECT_FALSE(map_.UpdatePacket(&packet_)); -} - -TEST_F(Vp9SsMapTest, UpdatePacket) { - auto& vp9_header = - absl::get(packet_.video_header.video_type_header); - EXPECT_TRUE(map_.Insert(packet_)); // kTemporalStructureMode3: 0-2-1-2.. - - vp9_header.gof_idx = 0; - EXPECT_TRUE(map_.UpdatePacket(&packet_)); - EXPECT_EQ(0, vp9_header.temporal_idx); - EXPECT_FALSE(vp9_header.temporal_up_switch); - EXPECT_EQ(1U, vp9_header.num_ref_pics); - EXPECT_EQ(4, vp9_header.pid_diff[0]); - - vp9_header.gof_idx = 1; - EXPECT_TRUE(map_.UpdatePacket(&packet_)); - EXPECT_EQ(2, vp9_header.temporal_idx); - EXPECT_TRUE(vp9_header.temporal_up_switch); - EXPECT_EQ(1U, vp9_header.num_ref_pics); - EXPECT_EQ(1, vp9_header.pid_diff[0]); - - vp9_header.gof_idx = 2; - EXPECT_TRUE(map_.UpdatePacket(&packet_)); - EXPECT_EQ(1, vp9_header.temporal_idx); - EXPECT_TRUE(vp9_header.temporal_up_switch); - EXPECT_EQ(1U, vp9_header.num_ref_pics); - EXPECT_EQ(2, vp9_header.pid_diff[0]); - - vp9_header.gof_idx = 3; - EXPECT_TRUE(map_.UpdatePacket(&packet_)); - EXPECT_EQ(2, vp9_header.temporal_idx); - EXPECT_TRUE(vp9_header.temporal_up_switch); - EXPECT_EQ(1U, vp9_header.num_ref_pics); - EXPECT_EQ(1, vp9_header.pid_diff[0]); -} - class TestBasicJitterBuffer : public ::testing::Test { protected: TestBasicJitterBuffer() {}