diff --git a/modules/video_coding/codecs/test/stats.cc b/modules/video_coding/codecs/test/stats.cc index 0aab931b52..009f74a580 100644 --- a/modules/video_coding/codecs/test/stats.cc +++ b/modules/video_coding/codecs/test/stats.cc @@ -32,8 +32,12 @@ std::string FrameStatistic::ToString() const { return ss.str(); } -FrameStatistic* Stats::AddFrame() { - stats_.emplace_back(stats_.size()); +FrameStatistic* Stats::AddFrame(size_t timestamp) { + RTC_DCHECK(rtp_timestamp_to_frame_num_.find(timestamp) == + rtp_timestamp_to_frame_num_.end()); + const size_t frame_number = stats_.size(); + rtp_timestamp_to_frame_num_[timestamp] = frame_number; + stats_.emplace_back(frame_number, timestamp); return &stats_.back(); } @@ -42,6 +46,12 @@ FrameStatistic* Stats::GetFrame(size_t frame_number) { return &stats_[frame_number]; } +FrameStatistic* Stats::GetFrameWithTimestamp(size_t timestamp) { + RTC_DCHECK(rtp_timestamp_to_frame_num_.find(timestamp) != + rtp_timestamp_to_frame_num_.end()); + return GetFrame(rtp_timestamp_to_frame_num_[timestamp]); +} + size_t Stats::size() const { return stats_.size(); } diff --git a/modules/video_coding/codecs/test/stats.h b/modules/video_coding/codecs/test/stats.h index 42a399c016..41a700ee21 100644 --- a/modules/video_coding/codecs/test/stats.h +++ b/modules/video_coding/codecs/test/stats.h @@ -11,6 +11,7 @@ #ifndef MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_ #define MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_ +#include #include #include @@ -21,7 +22,8 @@ namespace test { // Statistics for one processed frame. struct FrameStatistic { - explicit FrameStatistic(size_t frame_number) : frame_number(frame_number) {} + FrameStatistic(size_t frame_number, size_t rtp_timestamp) + : frame_number(frame_number), rtp_timestamp(rtp_timestamp) {} std::string ToString() const; @@ -72,15 +74,17 @@ class Stats { ~Stats() = default; // Creates a FrameStatistic for the next frame to be processed. - FrameStatistic* AddFrame(); + FrameStatistic* AddFrame(size_t timestamp); - // Returns the FrameStatistic corresponding to |frame_number|. + // Returns the FrameStatistic corresponding to |frame_number| or |timestamp|. FrameStatistic* GetFrame(size_t frame_number); + FrameStatistic* GetFrameWithTimestamp(size_t timestamp); size_t size() const; private: std::vector stats_; + std::map rtp_timestamp_to_frame_num_; }; } // namespace test diff --git a/modules/video_coding/codecs/test/stats_unittest.cc b/modules/video_coding/codecs/test/stats_unittest.cc index 08fe56fc6b..2e54a1e872 100644 --- a/modules/video_coding/codecs/test/stats_unittest.cc +++ b/modules/video_coding/codecs/test/stats_unittest.cc @@ -14,22 +14,40 @@ namespace webrtc { namespace test { +namespace { +const size_t kTimestamp = 12345; +} // namespace -TEST(StatsTest, AddSingleFrame) { +TEST(StatsTest, AddFrame) { Stats stats; - FrameStatistic* frame_stat = stats.AddFrame(); + FrameStatistic* frame_stat = stats.AddFrame(kTimestamp); EXPECT_EQ(0ull, frame_stat->frame_number); + EXPECT_EQ(kTimestamp, frame_stat->rtp_timestamp); EXPECT_EQ(1u, stats.size()); } -TEST(StatsTest, AddMultipleFrames) { +TEST(StatsTest, GetFrame) { + Stats stats; + stats.AddFrame(kTimestamp); + FrameStatistic* frame_stat = stats.GetFrame(0u); + EXPECT_EQ(0u, frame_stat->frame_number); + EXPECT_EQ(kTimestamp, frame_stat->rtp_timestamp); +} + +TEST(StatsTest, AddFrames) { Stats stats; const size_t kNumFrames = 1000; for (size_t i = 0; i < kNumFrames; ++i) { - FrameStatistic* frame_stat = stats.AddFrame(); + FrameStatistic* frame_stat = stats.AddFrame(kTimestamp + i); EXPECT_EQ(i, frame_stat->frame_number); + EXPECT_EQ(kTimestamp + i, frame_stat->rtp_timestamp); } EXPECT_EQ(kNumFrames, stats.size()); + // Get frame. + size_t i = 22; + FrameStatistic* frame_stat = stats.GetFrameWithTimestamp(kTimestamp + i); + EXPECT_EQ(i, frame_stat->frame_number); + EXPECT_EQ(kTimestamp + i, frame_stat->rtp_timestamp); } } // namespace test diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc index f7d1fc9832..168f6bbd77 100644 --- a/modules/video_coding/codecs/test/videoprocessor.cc +++ b/modules/video_coding/codecs/test/videoprocessor.cc @@ -164,11 +164,11 @@ void VideoProcessor::ProcessFrame() { // Use the frame number as the basis for timestamp to identify frames. Let the // first timestamp be non-zero, to not make the IvfFileWriter believe that we // want to use capture timestamps in the IVF files. + // TODO(asapersson): Time stamps jump back if framerate increases. const size_t rtp_timestamp = (frame_number + 1) * kVideoPayloadTypeFrequency / config_.codec_settings.maxFramerate; const int64_t render_time_ms = (frame_number + 1) * rtc::kNumMillisecsPerSec / config_.codec_settings.maxFramerate; - rtp_timestamp_to_frame_num_[rtp_timestamp] = frame_number; input_frames_[frame_number] = rtc::MakeUnique(buffer, static_cast(rtp_timestamp), render_time_ms, webrtc::kVideoRotation_0); @@ -176,8 +176,7 @@ void VideoProcessor::ProcessFrame() { std::vector frame_types = config_.FrameTypeForFrame(frame_number); // Create frame statistics object used for aggregation at end of test run. - FrameStatistic* frame_stat = stats_->AddFrame(); - frame_stat->rtp_timestamp = rtp_timestamp; + FrameStatistic* frame_stat = stats_->AddFrame(rtp_timestamp); // For the highest measurement accuracy of the encode time, the start/stop // time recordings should wrap the Encode call as tightly as possible. @@ -210,10 +209,11 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec, config_.encoded_frame_checker->CheckEncodedFrame(codec, encoded_image); } - const size_t frame_number = - rtp_timestamp_to_frame_num_[encoded_image._timeStamp]; + FrameStatistic* frame_stat = + stats_->GetFrameWithTimestamp(encoded_image._timeStamp); // Ensure strict monotonicity. + const size_t frame_number = frame_stat->frame_number; if (num_encoded_frames_ > 0) { RTC_CHECK_GT(frame_number, last_encoded_frame_num_); } @@ -228,7 +228,6 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec, last_encoded_frame_num_ = frame_number; // Update frame statistics. - FrameStatistic* frame_stat = stats_->GetFrame(frame_number); frame_stat->encode_time_us = GetElapsedTimeMicroseconds(frame_stat->encode_start_ns, encode_stop_ns); frame_stat->encoding_successful = true; @@ -280,9 +279,8 @@ void VideoProcessor::FrameDecoded(const VideoFrame& decoded_frame) { int64_t decode_stop_ns = rtc::TimeNanos(); // Update frame statistics. - const size_t frame_number = - rtp_timestamp_to_frame_num_[decoded_frame.timestamp()]; - FrameStatistic* frame_stat = stats_->GetFrame(frame_number); + FrameStatistic* frame_stat = + stats_->GetFrameWithTimestamp(decoded_frame.timestamp()); frame_stat->decoded_width = decoded_frame.width(); frame_stat->decoded_height = decoded_frame.height(); frame_stat->decode_time_us = @@ -290,6 +288,7 @@ void VideoProcessor::FrameDecoded(const VideoFrame& decoded_frame) { frame_stat->decoding_successful = true; // Ensure strict monotonicity. + const size_t frame_number = frame_stat->frame_number; if (num_decoded_frames_ > 0) { RTC_CHECK_GT(frame_number, last_decoded_frame_num_); } diff --git a/modules/video_coding/codecs/test/videoprocessor.h b/modules/video_coding/codecs/test/videoprocessor.h index 190b6a3134..6aaef5f946 100644 --- a/modules/video_coding/codecs/test/videoprocessor.h +++ b/modules/video_coding/codecs/test/videoprocessor.h @@ -218,11 +218,6 @@ class VideoProcessor { size_t num_encoded_frames_ RTC_GUARDED_BY(sequence_checker_); size_t num_decoded_frames_ RTC_GUARDED_BY(sequence_checker_); - // Store an RTP timestamp -> frame number map, since the timestamps are - // based off of the frame rate, which can change mid-test. - std::map rtp_timestamp_to_frame_num_ - RTC_GUARDED_BY(sequence_checker_); - // Keep track of if we have excluded the first key frame from packet loss. bool first_key_frame_has_been_excluded_ RTC_GUARDED_BY(sequence_checker_); diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index f9b0a72c62..fcdcd38440 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -574,7 +574,7 @@ void VideoProcessorIntegrationTest::AnalyzeAndPrintStats( Statistics qp; - FrameStatistic last_successfully_decoded_frame(0); + FrameStatistic last_successfully_decoded_frame(0, 0); for (size_t frame_idx = 0; frame_idx < stats.size(); ++frame_idx) { const FrameStatistic& frame_stat = stats[frame_idx];