Add Y4mFileReader

Encapsulate logic for reading .y4m video files in a single class. We
currently have spread out logic for opening .y4m files with partial
parsing. This CL consolidates this logic into a single class with a well
defined interface.

Change-Id: Id61673b3c95a0053b30e95b4cf382e1c6b05fc30
Bug: webrtc:9642
Reviewed-on: https://webrtc-review.googlesource.com/94772
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Paulina Hensman <phensman@webrtc.org>
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24398}
diff --git a/rtc_tools/frame_analyzer/frame_analyzer.cc b/rtc_tools/frame_analyzer/frame_analyzer.cc
index b3d9b94..f5a9c2b 100644
--- a/rtc_tools/frame_analyzer/frame_analyzer.cc
+++ b/rtc_tools/frame_analyzer/frame_analyzer.cc
@@ -17,6 +17,7 @@
 
 #include "rtc_tools/frame_analyzer/video_quality_analysis.h"
 #include "rtc_tools/simple_command_line_parser.h"
+#include "rtc_tools/y4m_file_reader.h"
 #include "test/testsupport/perf_test.h"
 
 /*
@@ -101,11 +102,19 @@
 
   webrtc::test::ResultsContainer results;
 
-  webrtc::test::RunAnalysis(parser.GetFlag("reference_file").c_str(),
-                            parser.GetFlag("test_file").c_str(),
-                            parser.GetFlag("stats_file_ref").c_str(),
-                            parser.GetFlag("stats_file_test").c_str(), width,
-                            height, &results);
+  rtc::scoped_refptr<webrtc::test::Y4mFile> reference_video =
+      webrtc::test::Y4mFile::Open(parser.GetFlag("reference_file"));
+  rtc::scoped_refptr<webrtc::test::Y4mFile> test_video =
+      webrtc::test::Y4mFile::Open(parser.GetFlag("test_file"));
+
+  if (!reference_video || !test_video) {
+    fprintf(stderr, "Error opening video files\n");
+    return 0;
+  }
+
+  webrtc::test::RunAnalysis(
+      reference_video, test_video, parser.GetFlag("stats_file_ref").c_str(),
+      parser.GetFlag("stats_file_test").c_str(), width, height, &results);
   webrtc::test::GetMaxRepeatedAndSkippedFrames(
       parser.GetFlag("stats_file_ref"), parser.GetFlag("stats_file_test"),
       &results);
diff --git a/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.cc b/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.cc
index 9a7535b..96e0ef4 100644
--- a/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.cc
+++ b/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.cc
@@ -25,36 +25,6 @@
 #define strtok_r strtok_s
 #endif
 
-void get_height_width_fps(int* height,
-                          int* width,
-                          int* fps,
-                          const std::string& video_file) {
-  // File header looks like :
-  //  YUV4MPEG2 W1280 H720 F25:1 Ip A0:0 C420mpeg2 XYSCSS=420MPEG2.
-  char frame_header[STATS_LINE_LENGTH];
-  FILE* input_file = fopen(video_file.c_str(), "rb");
-
-  size_t bytes_read = fread(frame_header, 1, STATS_LINE_LENGTH - 1, input_file);
-
-  frame_header[bytes_read] = '\0';
-  std::string file_header_stats[5];
-  int no_of_stats = 0;
-  char* save_ptr;
-  char* token = strtok_r(frame_header, " ", &save_ptr);
-
-  while (token != NULL) {
-    file_header_stats[no_of_stats++] = token;
-    token = strtok_r(NULL, " ", &save_ptr);
-  }
-
-  *width = std::stoi(file_header_stats[1].erase(0, 1));
-  *height = std::stoi(file_header_stats[2].erase(0, 1));
-  *fps = std::stoi(file_header_stats[3].erase(0, 1));
-
-  printf("Height: %d Width: %d fps:%d \n", *height, *width, *fps);
-  fclose(input_file);
-}
-
 bool frozen_frame(std::vector<double> psnr_per_frame,
                   std::vector<double> ssim_per_frame,
                   size_t frame) {
@@ -135,60 +105,29 @@
   printf("\n");
 }
 
-void compute_metrics(const std::string& video_file_name,
+void compute_metrics(const rtc::scoped_refptr<webrtc::test::Y4mFile>& video,
                      std::vector<double>* psnr_per_frame,
                      std::vector<double>* ssim_per_frame) {
-  int height = 0, width = 0, fps = 0;
-  get_height_width_fps(&height, &width, &fps, video_file_name);
-
-  int no_of_frames = 0;
-  int size = webrtc::test::GetI420FrameSize(width, height);
-
-  // Allocate buffers for test and reference frames.
-  uint8_t* current_frame = new uint8_t[size];
-  uint8_t* next_frame = new uint8_t[size];
-
-  while (true) {
-    if (!(webrtc::test::ExtractFrameFromY4mFile(video_file_name.c_str(), width,
-                                                height, no_of_frames,
-                                                current_frame))) {
-      break;
-    }
-
-    if (!(webrtc::test::ExtractFrameFromY4mFile(video_file_name.c_str(), width,
-                                                height, no_of_frames + 1,
-                                                next_frame))) {
-      break;
-    }
-
-    double result_psnr = webrtc::test::CalculateMetrics(
-        webrtc::test::kPSNR, current_frame, next_frame, width, height);
-    double result_ssim = webrtc::test::CalculateMetrics(
-        webrtc::test::kSSIM, current_frame, next_frame, width, height);
+  for (size_t i = 0; i < video->number_of_frames() - 1; ++i) {
+    const rtc::scoped_refptr<webrtc::I420BufferInterface> current_frame =
+        video->GetFrame(i);
+    const rtc::scoped_refptr<webrtc::I420BufferInterface> next_frame =
+        video->GetFrame(i + 1);
+    double result_psnr = webrtc::test::Psnr(current_frame, next_frame);
+    double result_ssim = webrtc::test::Ssim(current_frame, next_frame);
 
     psnr_per_frame->push_back(result_psnr);
     ssim_per_frame->push_back(result_ssim);
-    no_of_frames++;
   }
-  // Cleanup.
-  delete[] current_frame;
-  delete[] next_frame;
-}
-
-bool check_file_extension(const std::string& video_file_name) {
-  if (video_file_name.substr(video_file_name.length() - 3, 3) != "y4m") {
-    printf("Only y4m video file format is supported. Given: %s\n",
-           video_file_name.c_str());
-    return false;
-  }
-  return true;
 }
 
 int run_analysis(const std::string& video_file) {
   std::vector<double> psnr_per_frame;
   std::vector<double> ssim_per_frame;
-  if (check_file_extension(video_file)) {
-    compute_metrics(video_file, &psnr_per_frame, &ssim_per_frame);
+  rtc::scoped_refptr<webrtc::test::Y4mFile> video =
+      webrtc::test::Y4mFile::Open(video_file);
+  if (video) {
+    compute_metrics(video, &psnr_per_frame, &ssim_per_frame);
   } else {
     return -1;
   }
diff --git a/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.h b/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.h
index a1de03b..6da9f4e 100644
--- a/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.h
+++ b/rtc_tools/frame_analyzer/reference_less_video_analysis_lib.h
@@ -14,12 +14,7 @@
 #include <string>
 #include <vector>
 
-// Parse the file header to extract height, width and fps
-// for a given video file.
-void get_height_width_fps(int* height,
-                          int* width,
-                          int* fps,
-                          const std::string& video_file);
+#include "rtc_tools/y4m_file_reader.h"
 
 // Returns true if the frame is frozen based on psnr and ssim freezing
 // threshold values.
@@ -39,13 +34,10 @@
 
 // Compute the metrics like freezing score based on PSNR and SSIM values for a
 // given video file.
-void compute_metrics(const std::string& video_file_name,
+void compute_metrics(const rtc::scoped_refptr<webrtc::test::Y4mFile>& video,
                      std::vector<double>* psnr_per_frame,
                      std::vector<double>* ssim_per_frame);
 
-// Checks the file extension and return true if it is y4m.
-bool check_file_extension(const std::string& video_file_name);
-
 // Compute freezing score metrics and prints the metrics
 // for a list of video files.
 int run_analysis(const std::string& video_file);
diff --git a/rtc_tools/frame_analyzer/reference_less_video_analysis_unittest.cc b/rtc_tools/frame_analyzer/reference_less_video_analysis_unittest.cc
index 4e20532..2c3cf3a 100644
--- a/rtc_tools/frame_analyzer/reference_less_video_analysis_unittest.cc
+++ b/rtc_tools/frame_analyzer/reference_less_video_analysis_unittest.cc
@@ -20,16 +20,18 @@
 class ReferenceLessVideoAnalysisTest : public ::testing::Test {
  public:
   void SetUp() override {
-    video_file =
-        webrtc::test::ResourcePath("reference_less_video_test_file", "y4m");
+    video = webrtc::test::Y4mFile::Open(
+        webrtc::test::ResourcePath("reference_less_video_test_file", "y4m"));
+    ASSERT_TRUE(video);
   }
-  std::string video_file;
+
+  rtc::scoped_refptr<webrtc::test::Y4mFile> video;
   std::vector<double> psnr_per_frame;
   std::vector<double> ssim_per_frame;
 };
 
 TEST_F(ReferenceLessVideoAnalysisTest, MatchComputedMetrics) {
-  compute_metrics(video_file, &psnr_per_frame, &ssim_per_frame);
+  compute_metrics(video, &psnr_per_frame, &ssim_per_frame);
   EXPECT_EQ(74, (int)psnr_per_frame.size());
 
   ASSERT_NEAR(27.2f, psnr_per_frame[1], 0.1f);
@@ -39,26 +41,11 @@
   ASSERT_NEAR(0.9f, ssim_per_frame[5], 0.1f);
 }
 
-TEST_F(ReferenceLessVideoAnalysisTest, MatchHeightWidthFps) {
-  int height = 0, width = 0, fps = 0;
-  get_height_width_fps(&height, &width, &fps, video_file.c_str());
-  EXPECT_EQ(height, 720);
-  EXPECT_EQ(width, 1280);
-  EXPECT_EQ(fps, 25);
-}
-
 TEST_F(ReferenceLessVideoAnalysisTest, MatchIdenticalFrameClusters) {
-  compute_metrics(video_file, &psnr_per_frame, &ssim_per_frame);
+  compute_metrics(video, &psnr_per_frame, &ssim_per_frame);
   std::vector<int> identical_frame_clusters =
       find_frame_clusters(psnr_per_frame, ssim_per_frame);
   EXPECT_EQ(5, (int)identical_frame_clusters.size());
   EXPECT_EQ(1, identical_frame_clusters[0]);
   EXPECT_EQ(1, identical_frame_clusters[4]);
 }
-
-TEST_F(ReferenceLessVideoAnalysisTest, CheckFileExtension) {
-  EXPECT_TRUE(check_file_extension(video_file));
-  std::string txt_file =
-      webrtc::test::ResourcePath("video_quality_analysis_frame", "txt");
-  EXPECT_FALSE(check_file_extension(txt_file));
-}
diff --git a/rtc_tools/frame_analyzer/video_quality_analysis.cc b/rtc_tools/frame_analyzer/video_quality_analysis.cc
index 60a4a01..dda55b8 100644
--- a/rtc_tools/frame_analyzer/video_quality_analysis.cc
+++ b/rtc_tools/frame_analyzer/video_quality_analysis.cc
@@ -19,11 +19,10 @@
 #include <utility>
 
 #include "test/testsupport/perf_test.h"
+#include "third_party/libyuv/include/libyuv/compare.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
 
 #define STATS_LINE_LENGTH 32
-#define Y4M_FILE_HEADER_MAX_SIZE 200
-#define Y4M_FRAME_DELIMITER "FRAME"
-#define Y4M_FRAME_HEADER_SIZE 6
 
 namespace webrtc {
 namespace test {
@@ -92,160 +91,47 @@
   return true;
 }
 
-bool ExtractFrameFromYuvFile(const char* i420_file_name,
-                             int width,
-                             int height,
-                             int frame_number,
-                             uint8_t* result_frame) {
-  int frame_size = GetI420FrameSize(width, height);
-  int offset = frame_number * frame_size;  // Calculate offset for the frame.
-  bool errors = false;
-
-  FILE* input_file = fopen(i420_file_name, "rb");
-  if (input_file == NULL) {
-    fprintf(stderr, "Couldn't open input file for reading: %s\n",
-            i420_file_name);
-    return false;
-  }
-
-  // Change stream pointer to new offset.
-  fseek(input_file, offset, SEEK_SET);
-
-  size_t bytes_read = fread(result_frame, 1, frame_size, input_file);
-  if (bytes_read != static_cast<size_t>(frame_size) && ferror(input_file)) {
-    fprintf(stdout, "Error while reading frame no %d from file %s\n",
-            frame_number, i420_file_name);
-    errors = true;
-  }
-  fclose(input_file);
-  return !errors;
+template <typename FrameMetricFunction>
+static double CalculateMetric(
+    const FrameMetricFunction& frame_metric_function,
+    const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
+    const rtc::scoped_refptr<I420BufferInterface>& test_buffer) {
+  RTC_CHECK_EQ(ref_buffer->width(), test_buffer->width());
+  RTC_CHECK_EQ(ref_buffer->height(), test_buffer->height());
+  return frame_metric_function(
+      ref_buffer->DataY(), ref_buffer->StrideY(), ref_buffer->DataU(),
+      ref_buffer->StrideU(), ref_buffer->DataV(), ref_buffer->StrideV(),
+      test_buffer->DataY(), test_buffer->StrideY(), test_buffer->DataU(),
+      test_buffer->StrideU(), test_buffer->DataV(), test_buffer->StrideV(),
+      test_buffer->width(), test_buffer->height());
 }
 
-bool ExtractFrameFromY4mFile(const char* y4m_file_name,
-                             int width,
-                             int height,
-                             int frame_number,
-                             uint8_t* result_frame) {
-  int frame_size = GetI420FrameSize(width, height);
-  int inital_offset = frame_number * (frame_size + Y4M_FRAME_HEADER_SIZE);
-  int frame_offset = 0;
-
-  FILE* input_file = fopen(y4m_file_name, "rb");
-  if (input_file == NULL) {
-    fprintf(stderr, "Couldn't open input file for reading: %s\n",
-            y4m_file_name);
-    return false;
-  }
-
-  // YUV4MPEG2, a.k.a. Y4M File format has a file header and a frame header. The
-  // file header has the aspect: "YUV4MPEG2 C420 W640 H360 Ip F30:1 A1:1".
-  char frame_header[Y4M_FILE_HEADER_MAX_SIZE];
-  size_t bytes_read =
-      fread(frame_header, 1, Y4M_FILE_HEADER_MAX_SIZE - 1, input_file);
-  if (bytes_read != static_cast<size_t>(frame_size) && ferror(input_file)) {
-    fprintf(stdout, "Error while reading frame from file %s\n", y4m_file_name);
-    fclose(input_file);
-    return false;
-  }
-  frame_header[bytes_read] = '\0';
-  std::string header_contents(frame_header);
-  std::size_t found = header_contents.find(Y4M_FRAME_DELIMITER);
-  if (found == std::string::npos) {
-    fprintf(stdout, "Corrupted Y4M header, could not find \"FRAME\" in %s\n",
-            header_contents.c_str());
-    fclose(input_file);
-    return false;
-  }
-  frame_offset = static_cast<int>(found);
-
-  // Change stream pointer to new offset, skipping the frame header as well.
-  fseek(input_file, inital_offset + frame_offset + Y4M_FRAME_HEADER_SIZE,
-        SEEK_SET);
-
-  bytes_read = fread(result_frame, 1, frame_size, input_file);
-  if (feof(input_file)) {
-    fclose(input_file);
-    return false;
-  }
-  if (bytes_read != static_cast<size_t>(frame_size) && ferror(input_file)) {
-    fprintf(stdout, "Error while reading frame no %d from file %s\n",
-            frame_number, y4m_file_name);
-    fclose(input_file);
-    return false;
-  }
-
-  fclose(input_file);
-  return true;
+double Psnr(const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
+            const rtc::scoped_refptr<I420BufferInterface>& test_buffer) {
+  // LibYuv sets the max psnr value to 128, we restrict it to 48.
+  // In case of 0 mse in one frame, 128 can skew the results significantly.
+  return std::min(48.0,
+                  CalculateMetric(&libyuv::I420Psnr, ref_buffer, test_buffer));
 }
 
-double CalculateMetrics(VideoAnalysisMetricsType video_metrics_type,
-                        const uint8_t* ref_frame,
-                        const uint8_t* test_frame,
-                        int width,
-                        int height) {
-  if (!ref_frame || !test_frame)
-    return -1;
-  else if (height < 0 || width < 0)
-    return -1;
-  int half_width = (width + 1) >> 1;
-  int half_height = (height + 1) >> 1;
-  const uint8_t* src_y_a = ref_frame;
-  const uint8_t* src_u_a = src_y_a + width * height;
-  const uint8_t* src_v_a = src_u_a + half_width * half_height;
-  const uint8_t* src_y_b = test_frame;
-  const uint8_t* src_u_b = src_y_b + width * height;
-  const uint8_t* src_v_b = src_u_b + half_width * half_height;
-
-  int stride_y = width;
-  int stride_uv = half_width;
-
-  double result = 0.0;
-
-  switch (video_metrics_type) {
-    case kPSNR:
-      // In the following: stride is determined by width.
-      result = libyuv::I420Psnr(src_y_a, width, src_u_a, half_width, src_v_a,
-                                half_width, src_y_b, width, src_u_b, half_width,
-                                src_v_b, half_width, width, height);
-      // LibYuv sets the max psnr value to 128, we restrict it to 48.
-      // In case of 0 mse in one frame, 128 can skew the results significantly.
-      result = (result > 48.0) ? 48.0 : result;
-      break;
-    case kSSIM:
-      result = libyuv::I420Ssim(src_y_a, stride_y, src_u_a, stride_uv, src_v_a,
-                                stride_uv, src_y_b, stride_y, src_u_b,
-                                stride_uv, src_v_b, stride_uv, width, height);
-      break;
-    default:
-      assert(false);
-  }
-
-  return result;
+double Ssim(const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
+            const rtc::scoped_refptr<I420BufferInterface>& test_buffer) {
+  return CalculateMetric(&libyuv::I420Ssim, ref_buffer, test_buffer);
 }
 
-void RunAnalysis(const char* reference_file_name,
-                 const char* test_file_name,
+void RunAnalysis(const rtc::scoped_refptr<webrtc::test::Video>& reference_video,
+                 const rtc::scoped_refptr<webrtc::test::Video>& test_video,
                  const char* stats_file_reference_name,
                  const char* stats_file_test_name,
                  int width,
                  int height,
                  ResultsContainer* results) {
-  // Check if the reference_file_name ends with "y4m".
-  bool y4m_mode = false;
-  if (std::string(reference_file_name).find("y4m") != std::string::npos) {
-    y4m_mode = true;
-  }
-
-  int size = GetI420FrameSize(width, height);
   FILE* stats_file_ref = fopen(stats_file_reference_name, "r");
   FILE* stats_file_test = fopen(stats_file_test_name, "r");
 
   // String buffer for the lines in the stats file.
   char line[STATS_LINE_LENGTH];
 
-  // Allocate buffers for test and reference frames.
-  uint8_t* test_frame = new uint8_t[size];
-  uint8_t* reference_frame = new uint8_t[size];
   int previous_frame_number = -1;
 
   // Maps barcode id to the frame id for the reference video.
@@ -282,21 +168,14 @@
     assert(extracted_test_frame != -1);
     assert(decoded_frame_number != -1);
 
-    ExtractFrameFromYuvFile(test_file_name, width, height, extracted_test_frame,
-                            test_frame);
-    if (y4m_mode) {
-      ExtractFrameFromY4mFile(reference_file_name, width, height,
-                              extracted_ref_frame, reference_frame);
-    } else {
-      ExtractFrameFromYuvFile(reference_file_name, width, height,
-                              extracted_ref_frame, reference_frame);
-    }
+    const rtc::scoped_refptr<webrtc::I420BufferInterface> test_frame =
+        test_video->GetFrame(extracted_test_frame);
+    const rtc::scoped_refptr<webrtc::I420BufferInterface> reference_frame =
+        reference_video->GetFrame(extracted_ref_frame);
 
     // Calculate the PSNR and SSIM.
-    double result_psnr =
-        CalculateMetrics(kPSNR, reference_frame, test_frame, width, height);
-    double result_ssim =
-        CalculateMetrics(kSSIM, reference_frame, test_frame, width, height);
+    double result_psnr = Psnr(reference_frame, test_frame);
+    double result_ssim = Ssim(reference_frame, test_frame);
 
     previous_frame_number = decoded_frame_number;
 
@@ -312,8 +191,6 @@
   // Cleanup.
   fclose(stats_file_ref);
   fclose(stats_file_test);
-  delete[] test_frame;
-  delete[] reference_frame;
 }
 
 std::vector<std::pair<int, int> > CalculateFrameClusters(
diff --git a/rtc_tools/frame_analyzer/video_quality_analysis.h b/rtc_tools/frame_analyzer/video_quality_analysis.h
index dca719d..0ebd0c7 100644
--- a/rtc_tools/frame_analyzer/video_quality_analysis.h
+++ b/rtc_tools/frame_analyzer/video_quality_analysis.h
@@ -15,8 +15,8 @@
 #include <utility>
 #include <vector>
 
-#include "third_party/libyuv/include/libyuv/compare.h"
-#include "third_party/libyuv/include/libyuv/convert.h"
+#include "api/video/i420_buffer.h"
+#include "rtc_tools/y4m_file_reader.h"
 
 namespace webrtc {
 namespace test {
@@ -44,8 +44,6 @@
   int decode_errors_test;
 };
 
-enum VideoAnalysisMetricsType { kPSNR, kSSIM };
-
 // A function to run the PSNR and SSIM analysis on the test file. The test file
 // comprises the frames that were captured during the quality measurement test.
 // There may be missing or duplicate frames. Also the frames start at a random
@@ -61,23 +59,23 @@
 // problem with the decoding there would be 'Barcode error' instead of yyyy.
 // The stat files are used to compare the right frames with each other and
 // to calculate statistics.
-void RunAnalysis(const char* reference_file_name,
-                 const char* test_file_name,
+void RunAnalysis(const rtc::scoped_refptr<webrtc::test::Video>& reference_video,
+                 const rtc::scoped_refptr<webrtc::test::Video>& test_video,
                  const char* stats_file_reference_name,
                  const char* stats_file_test_name,
                  int width,
                  int height,
                  ResultsContainer* results);
 
-// Compute PSNR or SSIM for an I420 frame (all planes). When we are calculating
-// PSNR values, the max return value (in the case where the test and reference
-// frames are exactly the same) will be 48. In the case of SSIM the max return
-// value will be 1.
-double CalculateMetrics(VideoAnalysisMetricsType video_metrics_type,
-                        const uint8_t* ref_frame,
-                        const uint8_t* test_frame,
-                        int width,
-                        int height);
+// Compute PSNR for an I420 buffer (all planes). The max return value (in the
+// case where the test and reference frames are exactly the same) will be 48.
+double Psnr(const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
+            const rtc::scoped_refptr<I420BufferInterface>& test_buffer);
+
+// Compute SSIM for an I420 buffer (all planes). The max return value (in the
+// case where the test and reference frames are exactly the same) will be 1.
+double Ssim(const rtc::scoped_refptr<I420BufferInterface>& ref_buffer,
+            const rtc::scoped_refptr<I420BufferInterface>& test_buffer);
 
 // Prints the result from the analysis in Chromium performance
 // numbers compatible format to stdout. If the results object contains no frames
@@ -129,21 +127,6 @@
 // frame_0023 0284, we will get 284.
 int ExtractDecodedFrameNumber(std::string line);
 
-// Extracts an I420 frame at position frame_number from the raw YUV file.
-bool ExtractFrameFromYuvFile(const char* i420_file_name,
-                             int width,
-                             int height,
-                             int frame_number,
-                             uint8_t* result_frame);
-
-// Extracts an I420 frame at position frame_number from the Y4M file. The first
-// frame has corresponded |frame_number| 0.
-bool ExtractFrameFromY4mFile(const char* i420_file_name,
-                             int width,
-                             int height,
-                             int frame_number,
-                             uint8_t* result_frame);
-
 }  // namespace test
 }  // namespace webrtc
 
diff --git a/rtc_tools/frame_analyzer/video_quality_analysis_unittest.cc b/rtc_tools/frame_analyzer/video_quality_analysis_unittest.cc
index d1edb30..d9565b2 100644
--- a/rtc_tools/frame_analyzer/video_quality_analysis_unittest.cc
+++ b/rtc_tools/frame_analyzer/video_quality_analysis_unittest.cc
@@ -41,31 +41,6 @@
   std::string stats_filename_;
 };
 
-TEST_F(VideoQualityAnalysisTest, MatchExtractedY4mFrame) {
-  std::string video_file =
-      webrtc::test::ResourcePath("reference_less_video_test_file", "y4m");
-
-  std::string extracted_frame_from_video_file =
-      webrtc::test::ResourcePath("video_quality_analysis_frame", "txt");
-
-  int frame_height = 720, frame_width = 1280;
-  int frame_number = 2;
-  int size = GetI420FrameSize(frame_width, frame_height);
-  uint8_t* result_frame = new uint8_t[size];
-  uint8_t* expected_frame = new uint8_t[size];
-
-  FILE* input_file = fopen(extracted_frame_from_video_file.c_str(), "rb");
-  fread(expected_frame, 1, size, input_file);
-
-  ExtractFrameFromY4mFile(video_file.c_str(), frame_width, frame_height,
-                          frame_number, result_frame);
-
-  EXPECT_EQ(*expected_frame, *result_frame);
-  fclose(input_file);
-  delete[] result_frame;
-  delete[] expected_frame;
-}
-
 TEST_F(VideoQualityAnalysisTest, PrintAnalysisResultsEmpty) {
   ResultsContainer result;
   PrintAnalysisResults(logfile_, "Empty", &result);