From bbf146587a57ea5833ff649e4d4874c6c59e253f Mon Sep 17 00:00:00 2001 From: Rasmus Brandt Date: Mon, 5 Feb 2018 09:52:11 +0100 Subject: [PATCH] Delete dead code for video quality calculation. Previously, the only user of this code was the VideoProcessorIntegrationTest. We have now changed that test to directly calculate image quality metrics using libyuv, similar to how the full stack tests and browser tests work. Bug: webrtc:8448 Change-Id: Ia7a607d7ddc37741fba76d56aa7297851ffa1c6b Reviewed-on: https://webrtc-review.googlesource.com/43760 Commit-Queue: Rasmus Brandt Reviewed-by: Sergey Silkin Reviewed-by: Stefan Holmer Cr-Commit-Position: refs/heads/master@{#22341} --- .../test/videoprocessor_integrationtest.cc | 1 - test/BUILD.gn | 3 - test/testsupport/metrics/video_metrics.cc | 193 ------------------ test/testsupport/metrics/video_metrics.h | 121 ----------- .../metrics/video_metrics_unittest.cc | 147 ------------- 5 files changed, 465 deletions(-) delete mode 100644 test/testsupport/metrics/video_metrics.cc delete mode 100644 test/testsupport/metrics/video_metrics.h delete mode 100644 test/testsupport/metrics/video_metrics_unittest.cc diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index 08f2765ead..3debd4cf4d 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -36,7 +36,6 @@ #include "rtc_base/ptr_util.h" #include "system_wrappers/include/sleep.h" #include "test/testsupport/fileutils.h" -#include "test/testsupport/metrics/video_metrics.h" namespace webrtc { namespace test { diff --git a/test/BUILD.gn b/test/BUILD.gn index fcde65f40b..409be1a1a5 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -240,8 +240,6 @@ if (rtc_include_tests) { sources = [ "testsupport/frame_reader.h", "testsupport/frame_writer.h", - "testsupport/metrics/video_metrics.cc", - "testsupport/metrics/video_metrics.h", "testsupport/mock/mock_frame_reader.h", "testsupport/y4m_frame_writer.cc", "testsupport/yuv_frame_reader.cc", @@ -344,7 +342,6 @@ if (rtc_include_tests) { "rtp_file_writer_unittest.cc", "single_threaded_task_queue_unittest.cc", "testsupport/always_passing_unittest.cc", - "testsupport/metrics/video_metrics_unittest.cc", "testsupport/perf_test_unittest.cc", "testsupport/test_artifacts_unittest.cc", "testsupport/y4m_frame_writer_unittest.cc", diff --git a/test/testsupport/metrics/video_metrics.cc b/test/testsupport/metrics/video_metrics.cc deleted file mode 100644 index 8fa9ea350b..0000000000 --- a/test/testsupport/metrics/video_metrics.cc +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "test/testsupport/metrics/video_metrics.h" - -#include -#include - -#include // min_element, max_element -#include - -#include "api/video/i420_buffer.h" -#include "api/video/video_frame.h" -#include "common_video/libyuv/include/webrtc_libyuv.h" -#include "test/frame_utils.h" -#include "third_party/libyuv/include/libyuv/convert.h" - -namespace webrtc { -namespace test { - -// Copy here so our callers won't need to include libyuv for this constant. -double kMetricsPerfectPSNR = kPerfectPSNR; - -// Used for calculating min and max values. -static bool LessForFrameResultValue(const FrameResult& s1, - const FrameResult& s2) { - return s1.value < s2.value; -} - -enum VideoMetricsType { kPSNR, kSSIM, kBoth }; - -// Calculates metrics for a frame and adds statistics to the result for it. -void CalculateFrame(VideoMetricsType video_metrics_type, - const I420BufferInterface& ref, - const I420BufferInterface& test, - int frame_number, - QualityMetricsResult* result) { - FrameResult frame_result = {0, 0}; - frame_result.frame_number = frame_number; - switch (video_metrics_type) { - case kPSNR: - frame_result.value = I420PSNR(ref, test); - break; - case kSSIM: - frame_result.value = I420SSIM(ref, test); - break; - default: - assert(false); - } - result->frames.push_back(frame_result); -} - -// Calculates average, min and max values for the supplied struct, if non-NULL. -void CalculateStats(QualityMetricsResult* result) { - if (result == NULL || result->frames.size() == 0) { - return; - } - // Calculate average. - std::vector::iterator iter; - double metrics_values_sum = 0.0; - for (iter = result->frames.begin(); iter != result->frames.end(); ++iter) { - metrics_values_sum += iter->value; - } - result->average = metrics_values_sum / result->frames.size(); - - // Calculate min/max statistics. - iter = std::min_element(result->frames.begin(), result->frames.end(), - LessForFrameResultValue); - result->min = iter->value; - result->min_frame_number = iter->frame_number; - iter = std::max_element(result->frames.begin(), result->frames.end(), - LessForFrameResultValue); - result->max = iter->value; - result->max_frame_number = iter->frame_number; -} - -// Single method that handles all combinations of video metrics calculation, to -// minimize code duplication. Either psnr_result or ssim_result may be NULL, -// depending on which VideoMetricsType is targeted. -int CalculateMetrics(VideoMetricsType video_metrics_type, - const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* psnr_result, - QualityMetricsResult* ssim_result) { - assert(ref_filename != NULL); - assert(test_filename != NULL); - assert(width > 0); - assert(height > 0); - - FILE* ref_fp = fopen(ref_filename, "rb"); - if (ref_fp == NULL) { - // Cannot open reference file. - fprintf(stderr, "Cannot open file %s\n", ref_filename); - return -1; - } - FILE* test_fp = fopen(test_filename, "rb"); - if (test_fp == NULL) { - // Cannot open test file. - fprintf(stderr, "Cannot open file %s\n", test_filename); - fclose(ref_fp); - return -2; - } - int frame_number = 0; - - // Read reference and test frames. - for (;;) { - rtc::scoped_refptr ref_i420_buffer( - test::ReadI420Buffer(width, height, ref_fp)); - if (!ref_i420_buffer) - break; - - rtc::scoped_refptr test_i420_buffer( - test::ReadI420Buffer(width, height, test_fp)); - - if (!test_i420_buffer) - break; - - switch (video_metrics_type) { - case kPSNR: - CalculateFrame(kPSNR, *ref_i420_buffer, *test_i420_buffer, frame_number, - psnr_result); - break; - case kSSIM: - CalculateFrame(kSSIM, *ref_i420_buffer, *test_i420_buffer, frame_number, - ssim_result); - break; - case kBoth: - CalculateFrame(kPSNR, *ref_i420_buffer, *test_i420_buffer, frame_number, - psnr_result); - CalculateFrame(kSSIM, *ref_i420_buffer, *test_i420_buffer, frame_number, - ssim_result); - break; - } - frame_number++; - } - int return_code = 0; - if (frame_number == 0) { - fprintf(stderr, "Tried to measure video metrics from empty files " - "(reference file: %s test file: %s)\n", ref_filename, - test_filename); - return_code = -3; - } else { - CalculateStats(psnr_result); - CalculateStats(ssim_result); - } - fclose(ref_fp); - fclose(test_fp); - return return_code; -} - -int I420MetricsFromFiles(const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* psnr_result, - QualityMetricsResult* ssim_result) { - assert(psnr_result != NULL); - assert(ssim_result != NULL); - return CalculateMetrics(kBoth, ref_filename, test_filename, width, height, - psnr_result, ssim_result); -} - -int I420PSNRFromFiles(const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* result) { - assert(result != NULL); - return CalculateMetrics(kPSNR, ref_filename, test_filename, width, height, - result, NULL); -} - -int I420SSIMFromFiles(const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* result) { - assert(result != NULL); - return CalculateMetrics(kSSIM, ref_filename, test_filename, width, height, - NULL, result); -} - -} // namespace test -} // namespace webrtc diff --git a/test/testsupport/metrics/video_metrics.h b/test/testsupport/metrics/video_metrics.h deleted file mode 100644 index f72ea9b7bb..0000000000 --- a/test/testsupport/metrics/video_metrics.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef TESTSUPPORT_METRICS_VIDEO_METRICS_H_ -#define TESTSUPPORT_METRICS_VIDEO_METRICS_H_ - -#include -#include - -namespace webrtc { -namespace test { - -// The highest PSNR value our algorithms will return. -extern double kMetricsPerfectPSNR; - -// Contains video quality metrics result for a single frame. -struct FrameResult { - int frame_number; - double value; -}; - -// Result from a PSNR/SSIM calculation operation. -// The frames in this data structure are 0-indexed. -struct QualityMetricsResult { - QualityMetricsResult() : - average(0.0), - min(std::numeric_limits::max()), - max(std::numeric_limits::min()), - min_frame_number(-1), - max_frame_number(-1) - {}; - double average; - double min; - double max; - int min_frame_number; - int max_frame_number; - std::vector frames; -}; - -// Calculates PSNR and SSIM values for the reference and test video files -// (must be in I420 format). All calculated values are filled into the -// QualityMetricsResult structs. -// -// PSNR values have the unit decibel (dB) where a high value means the test file -// is similar to the reference file. The higher value, the more similar. The -// maximum PSNR value is kMetricsInfinitePSNR. For more info about PSNR, see -// http://en.wikipedia.org/wiki/PSNR. -// -// SSIM values range between -1.0 and 1.0, where 1.0 means the files are -// identical. For more info about SSIM, see http://en.wikipedia.org/wiki/SSIM -// This function only compares video frames up to the point when the shortest -// video ends. -// Return value: -// 0 if successful, negative on errors: -// -1 if the source file cannot be opened -// -2 if the test file cannot be opened -// -3 if any of the files are empty -// -4 if any arguments are invalid. -int I420MetricsFromFiles(const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* psnr_result, - QualityMetricsResult* ssim_result); - -// Calculates PSNR values for the reference and test video files (must be in -// I420 format). All calculated values are filled into the QualityMetricsResult -// struct. -// -// PSNR values have the unit decibel (dB) where a high value means the test file -// is similar to the reference file. The higher value, the more similar. The -// maximum PSNR value is kMetricsInfinitePSNR. For more info about PSNR, see -// http://en.wikipedia.org/wiki/PSNR. -// -// This function only compares video frames up to the point when the shortest -// video ends. -// -// Return value: -// 0 if successful, negative on errors: -// -1 if the source file cannot be opened -// -2 if the test file cannot be opened -// -3 if any of the files are empty -// -4 if any arguments are invalid. -int I420PSNRFromFiles(const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* result); - -// Calculates SSIM values for the reference and test video files (must be in -// I420 format). All calculated values are filled into the QualityMetricsResult -// struct. -// SSIM values range between -1.0 and 1.0, where 1.0 means the files are -// identical. -// This function only compares video frames up to the point when the shortest -// video ends. -// For more info about SSIM, see http://en.wikipedia.org/wiki/SSIM -// -// Return value: -// 0 if successful, negative on errors: -// -1 if the source file cannot be opened -// -2 if the test file cannot be opened -// -3 if any of the files are empty -// -4 if any arguments are invalid. -int I420SSIMFromFiles(const char* ref_filename, - const char* test_filename, - int width, - int height, - QualityMetricsResult* result); - -} // namespace test -} // namespace webrtc - -#endif // TESTSUPPORT_METRICS_VIDEO_METRICS_H_ diff --git a/test/testsupport/metrics/video_metrics_unittest.cc b/test/testsupport/metrics/video_metrics_unittest.cc deleted file mode 100644 index 5b00458761..0000000000 --- a/test/testsupport/metrics/video_metrics_unittest.cc +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "test/testsupport/metrics/video_metrics.h" - -#include "test/gtest.h" -#include "test/testsupport/fileutils.h" - -namespace webrtc { - -static const int kWidth = 352; -static const int kHeight = 288; - -static const int kMissingReferenceFileReturnCode = -1; -static const int kMissingTestFileReturnCode = -2; -static const int kEmptyFileReturnCode = -3; -static const double kPsnrPerfectResult = 48.0; -static const double kSsimPerfectResult = 1.0; - -class VideoMetricsTest: public testing::Test { - protected: - VideoMetricsTest() { - video_file_ = webrtc::test::ResourcePath("foreman_cif_short", "yuv"); - } - virtual ~VideoMetricsTest() {} - void SetUp() { - non_existing_file_ = webrtc::test::OutputPath() + - "video_metrics_unittest_non_existing"; - remove(non_existing_file_.c_str()); // To be sure it doesn't exist. - - // Create an empty file: - empty_file_ = webrtc::test::TempFilename( - webrtc::test::OutputPath(), "video_metrics_unittest_empty_file"); - FILE* dummy = fopen(empty_file_.c_str(), "wb"); - fclose(dummy); - } - void TearDown() { - remove(empty_file_.c_str()); - } - webrtc::test::QualityMetricsResult psnr_result_; - webrtc::test::QualityMetricsResult ssim_result_; - std::string non_existing_file_; - std::string empty_file_; - std::string video_file_; -}; - -// Tests that it is possible to run with the same reference as test file -TEST_F(VideoMetricsTest, ReturnsPerfectResultForIdenticalFilesPSNR) { - EXPECT_EQ(0, I420PSNRFromFiles(video_file_.c_str(), video_file_.c_str(), - kWidth, kHeight, &psnr_result_)); - EXPECT_EQ(kPsnrPerfectResult, psnr_result_.average); -} - -TEST_F(VideoMetricsTest, ReturnsPerfectResultForIdenticalFilesSSIM) { - EXPECT_EQ(0, I420SSIMFromFiles(video_file_.c_str(), video_file_.c_str(), - kWidth, kHeight, &ssim_result_)); - EXPECT_EQ(kSsimPerfectResult, ssim_result_.average); -} - -TEST_F(VideoMetricsTest, ReturnsPerfectResultForIdenticalFilesBothMetrics) { - EXPECT_EQ(0, I420MetricsFromFiles(video_file_.c_str(), video_file_.c_str(), - kWidth, kHeight, &psnr_result_, - &ssim_result_)); - EXPECT_EQ(kPsnrPerfectResult, psnr_result_.average); - EXPECT_EQ(kSsimPerfectResult, ssim_result_.average); -} - -// Tests that the right return code is given when the reference file is missing. -TEST_F(VideoMetricsTest, MissingReferenceFilePSNR) { - EXPECT_EQ(kMissingReferenceFileReturnCode, - I420PSNRFromFiles(non_existing_file_.c_str(), - video_file_.c_str(), kWidth, kHeight, - &ssim_result_)); -} - -TEST_F(VideoMetricsTest, MissingReferenceFileSSIM) { - EXPECT_EQ(kMissingReferenceFileReturnCode, - I420SSIMFromFiles(non_existing_file_.c_str(), - video_file_.c_str(), kWidth, kHeight, - &ssim_result_)); -} - -TEST_F(VideoMetricsTest, MissingReferenceFileBothMetrics) { - EXPECT_EQ(kMissingReferenceFileReturnCode, - I420MetricsFromFiles(non_existing_file_.c_str(), - video_file_.c_str(), kWidth, kHeight, - &psnr_result_, &ssim_result_)); -} - -// Tests that the right return code is given when the test file is missing. -TEST_F(VideoMetricsTest, MissingTestFilePSNR) { - EXPECT_EQ(kMissingTestFileReturnCode, - I420PSNRFromFiles(video_file_.c_str(), non_existing_file_.c_str(), - kWidth, kHeight, &ssim_result_)); -} - -TEST_F(VideoMetricsTest, MissingTestFileSSIM) { - EXPECT_EQ(kMissingTestFileReturnCode, - I420SSIMFromFiles(video_file_.c_str(), non_existing_file_.c_str(), - kWidth, kHeight, &ssim_result_)); -} - -TEST_F(VideoMetricsTest, MissingTestFileBothMetrics) { - EXPECT_EQ(kMissingTestFileReturnCode, - I420MetricsFromFiles(video_file_.c_str(), - non_existing_file_.c_str(), kWidth, kHeight, - &psnr_result_, &ssim_result_)); -} - -// Tests that the method can be executed with empty files. -TEST_F(VideoMetricsTest, EmptyFilesPSNR) { - EXPECT_EQ(kEmptyFileReturnCode, - I420PSNRFromFiles(empty_file_.c_str(), video_file_.c_str(), - kWidth, kHeight, &ssim_result_)); - EXPECT_EQ(kEmptyFileReturnCode, - I420PSNRFromFiles(video_file_.c_str(), empty_file_.c_str(), - kWidth, kHeight, &ssim_result_)); -} - -TEST_F(VideoMetricsTest, EmptyFilesSSIM) { - EXPECT_EQ(kEmptyFileReturnCode, - I420SSIMFromFiles(empty_file_.c_str(), video_file_.c_str(), - kWidth, kHeight, &ssim_result_)); - EXPECT_EQ(kEmptyFileReturnCode, - I420SSIMFromFiles(video_file_.c_str(), empty_file_.c_str(), - kWidth, kHeight, &ssim_result_)); -} - -TEST_F(VideoMetricsTest, EmptyFilesBothMetrics) { - EXPECT_EQ(kEmptyFileReturnCode, - I420MetricsFromFiles(empty_file_.c_str(), video_file_.c_str(), - kWidth, kHeight, - &psnr_result_, &ssim_result_)); - EXPECT_EQ(kEmptyFileReturnCode, - I420MetricsFromFiles(video_file_.c_str(), empty_file_.c_str(), - kWidth, kHeight, - &psnr_result_, &ssim_result_)); -} - -} // namespace webrtc